
package view
{
    import model.CountryDataProvider;
    import model.DictionaryProxy;

    import constants.DialogType;
    import model.UserProxy;
    import model.vo.CountryVO;
    import model.vo.UserVO;

    import mx.collections.ArrayCollection;
    import mx.collections.IList;
    import mx.core.FlexGlobals;
    import mx.core.IFlexDisplayObject;
    import mx.core.UIComponent;
    import mx.events.CloseEvent;
    import mx.managers.PopUpManager;
    import mx.olap.aggregators.CountAggregator;
    import mx.resources.IResourceManager;
    import mx.resources.ResourceManager;

    import org.kolonitsky.alexey.debug.DebugWrapper;
    import org.puremvc.as3.interfaces.INotification;
    import org.puremvc.as3.patterns.mediator.Mediator;

    import view.dialogs.ErrorDialog;
    import view.dialogs.SinginDialog;
    import view.events.UserEvent;

    [ResourceBundle("elfinErrors")]

    /**
     *
     */
    public class DialogMediator extends Mediator {

        public static const NAME:String = "dialogMediator";

        public function DialogMediator()
        {
            super(NAME, null);
            DebugWrapper.trace("INFO: " + getMediatorName() + " created.")
        }

        public function get app():Elfin
        {
            return FlexGlobals.topLevelApplication as Elfin;
        }


        //-------------------------------------------------------------------------
        //
        //  Override mediator logic
        //
        //-------------------------------------------------------------------------

        override public function onRegister():void
        {
            super.onRegister();
        }

        override public function onRemove():void
        {
            super.onRemove();
        }

        override public function listNotificationInterests():Array
        {
            return [
                AppFacade.SHOW_DIALOG,
                UserProxy.USER_AUTHORIZATION,
                UserProxy.PASSWORD_RESTORED,
                DictionaryProxy.UPDATE
            ];
        }

        override public function handleNotification(notification:INotification):void
        {
            super.handleNotification(notification);

            switch (notification.getName())
            {
                case AppFacade.SHOW_DIALOG:
                {
                    DebugWrapper.trace("INFO: DialogMediator Catch SHOW_DIALOG notification");
                    addDialogToQueue(notification.getType(), notification.getBody());
                    break;
                }

                case UserProxy.USER_AUTHORIZATION:
                {
                    // Authorization success and open signin dialog close it
                    DebugWrapper.trace("INFO: DialogMediator. Close dialog");
                    var user:UserVO = notification.getBody() as UserVO;
                    if (user && user.authorized && currentDialogType == DialogType.SIGNIN)
                        currentDialog["close"]();
                    break;
                }

                case UserProxy.PASSWORD_RESTORED:
                {
                    (currentDialog as UIComponent).errorString = "";
                    (currentDialog as SinginDialog).notificationString = "Инструкции по восстановлению пароля были высланы вам на почту.";
                    break;
                }

                case DictionaryProxy.UPDATE:
                {
                    countries = notification.getBody() as CountryDataProvider;
                    break;
                }
            }
        }





        //-------------------------------------------------------------------------
        //
        //  Override mediator logic
        //
        //-------------------------------------------------------------------------

        /**
         * Dialog queue
         */
        private var dialogs:Array = [];

        /**
         *
         */
        private var currentDialog:IFlexDisplayObject = null;


        //---------------------------------
        // countries
        //---------------------------------

        private var _countries:CountryDataProvider = null;

        public function get countries():CountryDataProvider
        {
            return _countries;
        }

        public function set countries(value:CountryDataProvider):void
        {
            _countries = value;
            if (currentDialog && "countries" in currentDialog)
                currentDialog["countries"] = _countries;
        }


        //---------------------------------
        // currentDialogType
        //---------------------------------

        /**
         *
         */
        private function get currentDialogType():String
        {
            if (currentDialog == null)
                return "";

            for (var p:String in dialogTypes)
                if (currentDialog is dialogTypes[p])
                    return p;

            return "";
        }

        private var dialogTypes:Object =
        {
            "signin": SinginDialog,
            "error": ErrorDialog
        };

        /**
         * Push apropriate dialog and pass content object to it
         *
         * @param type notification type
         * @param content notification body
         */
        private function addDialogToQueue(type:String, content:Object):void
        {
            if (type == "")
                DebugWrapper.trace("WARRNING: Dialog type not assigned to showed dialog");

            switch (type)
            {
                case DialogType.SIGNIN:
                {
                    var signinDialog:SinginDialog = new SinginDialog();
                    signinDialog.currentState = "signin";
                    signinDialog.user = content as UserVO;
                    signinDialog.countries = countries;
                    signinDialog.horizontalCenter = 0;
                    signinDialog.verticalCenter = 0;
                    signinDialog.addEventListener(UserEvent.SIGNIN, signinHandler);
                    signinDialog.addEventListener(UserEvent.SIGNUP, signupHandler);
                    signinDialog.addEventListener(UserEvent.FORGOT_PASSWORD, forgetPasswordHandler);
                    dialogs.push(signinDialog);

                    sendNotification(Config.COUNTY_INFO_GET);
                    break;
                }

                case DialogType.SIGNUP:
                {
                    var signupDialog:SinginDialog = new SinginDialog();
                    signupDialog.currentState = "signup";
                    signupDialog.user = content as UserVO;
                    signupDialog.countries = countries;
                    signupDialog.horizontalCenter = 0;
                    signupDialog.verticalCenter = 0;
                    signupDialog.addEventListener(UserEvent.SIGNIN, signinHandler);
                    signupDialog.addEventListener(UserEvent.SIGNUP, signupHandler);
                    signupDialog.addEventListener(UserEvent.FORGOT_PASSWORD, forgetPasswordHandler);
                    dialogs.push(signupDialog);

                    sendNotification(Config.COUNTY_INFO_GET);
                    break;
                }

                case DialogType.ERROR:
                {
                    var rm:IResourceManager = ResourceManager.getInstance();
                    var ht:String = rm.getString("elfinErrors", "e" + content.errorID);

                    if (currentDialogType == "signin")
                    {
                        (currentDialog as UIComponent).errorString = ht;
                        break;
                    }

                    var errorDialog:ErrorDialog = new ErrorDialog();
                    errorDialog.headerText = ht;
                    errorDialog.text = content.text;
                    dialogs.push(errorDialog);
                    break;
                }

                default:
                {
                    DebugWrapper.trace("WARNING: Don't handleled dialog type: " + type);
                    break;
                }
            }

            if (dialogs.length)
                showDialog();
        }



        private function showDialog():void
        {
            // exit if dialog queue is empty or if dialog is shown currently
            if (dialogs.length == 0 || currentDialog)
                return;

            currentDialog = dialogs.shift() as IFlexDisplayObject;
            currentDialog.addEventListener(CloseEvent.CLOSE, currentDialog_closeHandler);

            PopUpManager.addPopUp(currentDialog, app, true);
            PopUpManager.centerPopUp(currentDialog)
        }

        private function currentDialog_closeHandler(event:CloseEvent):void
        {
            PopUpManager.removePopUp(currentDialog);
            showDialog();
        }

        private function signinHandler(event:UserEvent):void
        {
            //TODO: Set busy state
            sendNotification(Config.USER_SIGN_IN, event.user)
        }

        private function signupHandler(event:UserEvent):void
        {
            //TODO: Set busy state
            sendNotification(Config.USER_SIGN_UP, event.user)
        }

        private function forgetPasswordHandler(event:UserEvent):void
        {
            sendNotification(Config.USER_PASSWORD);
        }

    }
}
